做出一個物件,其可能是 int
或是 double
union
跟 struct
的語法非常像,但他們代表的是不一樣的意義
考慮以下 C 語言程式碼:
union {
int i;
double d;
} u;
struct {
int i;
double d;
} s;
union
u
跟 struct
s
在記憶體中的存放方式為:
s(Structure) u(Union)
+-- +--------+ +-- +--------+ --+
| | | | | | |
| +--------+ | +--------+ |
| | | | | | |
i | +--------+ i | +--------+ |
| | | | | | |
| +--------+ | +--------+ |
| | | | | | |
+-- +--------+ --+ +-- +--------+ | d
| | | | | |
+--------+ | +--------+ |
| | | | | |
+--------+ | +--------+ |
| | | | | |
+--------+ | +--------+ |
| | | | | |
+--------+ | d +--------+ --+
| | |
+--------+ |
| | |
+--------+ |
| | |
+--------+ |
| | |
+--------+ --+
union
只可以放 i
跟 d
擇一放一個
例如:
u.i = 82;
這時候 i
的位置就放了 82 進去,而這時候再寫:
u.d = 74.8;
原本 i
的值就被蓋掉了,整個 u
都被拿來放 74.8
利用這個特性就可以做出泛行的效果,但還必須要用 enum
來紀錄他是 int
還是 double
才行
enum SUIT {
CLUBS,
DIAMONDS,
HEARTS,
SPADES
};
其實就跟
#define SUIT int
#define CLUBS 0
#define DIAMONDS 1
#define HEARTS 2
#define SPADES 3
有一樣的效果
typedef struct {
enum (INT_KIND, DOUBLE_KIND) kind;
union {
int i;
double d;
} u;
} Number;
想塞 (int) 82
時:
Number n;
n.kind = INT_KIND;
n.u.i = 82;
想塞 (double) 74.8
時:
Number n;
n.kind = DOUBLE_KIND;
n.u.i = 74.8;
想 print 出來時:
void print_number(Number n)
{
if (n.kind == INT_KIND)
printf("%d", n.u.i);
else if (n.kind == INT_KIND)
printf("%g", n.u.d);
}
C Programming: A Modern Approach, 2/e